package org.fujay.commons.langchain4j.rag.assistant;

import dev.langchain4j.service.*;

/**
 * 定义RAG增强聊天助手接口，使用AIService自动实现
 * 支持思维链提示和来源引用
 */
public interface RagAssistant {

    /**
     * 基础RAG对话
     *
     * @param userMessage 用户消息
     * @return 助手响应
     */
    @SystemMessage("""
            你是一个专业的分析助手。请基于检索到的信息回答问题。
            如果无法从检索信息中找到答案，请诚实地表示不知道。
            如果回答基于检索的信息，请在回答中引用来源。
            """)
    TokenStream chat(String userMessage);

    /**
     * 思维链RAG对话
     *
     * @param userMessage 用户消息
     * @return 按思维链格式组织的助手响应
     */
    @SystemMessage("""
            你是一个专业的分析助手。请基于检索到的信息回答问题。
            思考步骤：
            1. 分析问题的关键要点
            2. 查找相关信息并评估其相关性
            3. 推理解答过程
            4. 给出完整回答
            5. 引用信息来源
            
            请按以下格式组织你的回答：
            分析: [分析问题要点]
            思考: [查找信息并推理]
            回答: [最终答案]
            引用: [列出使用的文档来源]
            """)
    TokenStream chatWithChainOfThought(String userMessage);

    /**
     * 带系统提示的RAG对话
     *
     * @param systemMessage 系统消息
     * @param userMessage   用户消息
     * @return 助手响应
     */
    @SystemMessage("{{sys}}")
    TokenStream chatWithSystem(@V("sys") String systemMessage, String userMessage);

    /**
     * 使用对话历史记忆进行RAG对话
     *
     * @param memoryId    会话ID
     * @param userMessage 用户消息
     * @return 助手响应
     */
    @SystemMessage(""" 
            你是一个专业的分析助手。请基于检索到的信息和我们之前的对话回答问题。
            如果无法从检索信息或对话历史中找到答案，请诚实地表示不知道。
            如果回答基于检索的信息，请在回答中引用来源。
            """)
    TokenStream chatWithMemory(@MemoryId String memoryId, String userMessage);

    /**
     * 完整RAG对话方法
     *
     * @param memoryId      会话ID
     * @param systemMessage 系统消息
     * @param userMessage   用户消息
     * @return 助手响应
     */
    @SystemMessage("{{sys}}")
    TokenStream chatWith(@MemoryId String memoryId, @V("sys") String systemMessage, @UserMessage String userMessage);

    /**
     * 专家角色RAG对话
     *
     * @param domain      领域名称，如"医疗"、"法律"、"技术"等
     * @param userMessage 用户消息
     * @return 助手响应
     */
    @SystemMessage("""
            你是一个{{domain}}领域的专家。请基于检索到的信息，以专业的{{domain}}领域视角回答问题。
            如果无法从检索信息中找到答案，请诚实地表示作为{{domain}}专家无法提供准确的回答。
            如果回答基于检索的信息，请在回答中引用来源。
            """)
    TokenStream chatAsExpert(@V("domain") String domain, String userMessage);
}